package com.marketing.auth.controller;

import com.marketing.auth.dto.LoginRequest;
import com.marketing.auth.dto.LoginResponse;
import com.marketing.auth.dto.UserInfoDto;
import com.marketing.auth.entity.User;
import com.marketing.auth.service.TokenService;
import com.marketing.auth.service.UserService;
import com.marketing.auth.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 * 处理网关路由的认证相关请求
 *
 * @author Marketing System
 * @version 1.0
 */
@RestController
public class AuthController {

    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    @Value("${server.port}")
    private int serverPort;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private JwtUtil jwtUtil;
        
    @Autowired
    private TokenService tokenService;

    /**
     * 健康检查接口（根路径）
     */
    @GetMapping("/health")
    public Map<String, Object> health() {
        logger.debug("收到健康检查请求");
        
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("service", "auth-service");
        response.put("timestamp", System.currentTimeMillis());
        response.put("message", "认证服务运行正常");
        
        logger.debug("健康检查响应: {}", response);
        return response;
    }

    /**
     * 测试路由接口（根路径）
     */
    @GetMapping("/test")
    public Map<String, Object> test() {
        logger.info("收到路由测试请求，服务端口: {}", serverPort);
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("service", "auth-service");
        response.put("message", "网关路由测试成功");
        response.put("timestamp", System.currentTimeMillis());
        response.put("path", "/test");
        response.put("note", "通过API网关路由访问");
        response.put("serverPort", serverPort); // 添加端口信息用于负载均衡验证
        
        logger.info("路由测试响应成功，端口: {}", serverPort);
        return response;
    }

    /**
     * 用户登录接口
     */
    @PostMapping("/login")
    public ResponseEntity<LoginResponse> login(@Valid @RequestBody LoginRequest loginRequest) {
        logger.info("收到用户登录请求，用户名: {}", loginRequest.getUsername());
        
        try {
            LoginResponse response = userService.login(loginRequest);
            
            // 添加服务器端口信息用于负载均衡验证
            if (response.getSuccess()) {
                logger.info("用户登录成功，用户名: {}, Token已生成并存储到Redis", loginRequest.getUsername());
                // 登录成功时返回200状态码
                return ResponseEntity.ok(response);
            } else {
                logger.warn("用户登录失败，用户名: {}, 原因: {}", loginRequest.getUsername(), response.getMessage());
                // 登录失败时返回401状态码
                return ResponseEntity.status(401).body(response);
            }
        } catch (Exception e) {
            logger.error("用户登录过程中发生异常，用户名: {}, 异常: {}", loginRequest.getUsername(), e.getMessage(), e);
            LoginResponse errorResponse = new LoginResponse(false, "登录过程中发生系统错误");
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * Token验证接口（支持会话续期）
     */
    @PostMapping("/verify")
    public ResponseEntity<Map<String, Object>> verifyToken(@RequestHeader("Authorization") String authHeader) {
        logger.debug("收到Token验证请求");
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                logger.warn("Token验证失败：Token格式不正确，authHeader: {}", authHeader);
                response.put("success", false);
                response.put("message", "Token格式不正确");
                return ResponseEntity.status(401).body(response);
            }
            
            String token = authHeader.substring(7); // 去掉 "Bearer " 前缀
            logger.debug("开始验证Token: {}...", token.length() > 20 ? token.substring(0, 20) + "..." : token);
            
            // 1. 首先检查JWT Token本身的有效性
            if (jwtUtil.isTokenExpired(token)) {
                logger.warn("Token验证失败：JWT Token已过期");
                response.put("success", false);
                response.put("message", "Token已过期");
                return ResponseEntity.status(401).body(response);
            }
            logger.debug("JWT Token有效性检查通过");
            
            // 2. 检查Token是否在Redis中存在
            if (!tokenService.isTokenValid(token)) {
                logger.warn("Token验证失败：Token在Redis中不存在或已失效");
                response.put("success", false);
                response.put("message", "Token已失效或已登出");
                return ResponseEntity.status(401).body(response);
            }
            logger.debug("Redis Token存在性检查通过");
            
            // 3. 从 Redis 获取用户信息
            UserInfoDto userInfo = tokenService.getUserByToken(token);
            if (userInfo == null) {
                logger.error("Token验证失败：无法从Redis获取用户信息");
                response.put("success", false);
                response.put("message", "用户信息不存在");
                return ResponseEntity.status(401).body(response);
            }
            logger.debug("从Redis获取用户信息成功，用户ID: {}, 用户名: {}", userInfo.getId(), userInfo.getUsername());
            
            // 4. 会话续期（将Token过期时间延长）
            boolean refreshed = tokenService.refreshToken(token, jwtUtil.getExpirationTimeInSeconds());
            if (refreshed) {
                logger.info("用户会话自动续期成功，用户: {}, 续期时长: {}秒", userInfo.getUsername(), jwtUtil.getExpirationTimeInSeconds());
            } else {
                logger.warn("用户会话续期失败，用户: {}", userInfo.getUsername());
            }
            
            response.put("success", true);
            response.put("message", "Token有效" + (refreshed ? "，已续期" : ""));
            response.put("username", userInfo.getUsername());
            response.put("userId", userInfo.getId());
            response.put("userInfo", userInfo);
            response.put("serverPort", serverPort);
            response.put("refreshed", refreshed);
            
            logger.debug("Token验证成功，用户: {}, 续期状态: {}", userInfo.getUsername(), refreshed);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("Token验证过程中发生异常: {}", e.getMessage(), e);
            response.put("success", false);
            response.put("message", "Token解析失败: " + e.getMessage());
            return ResponseEntity.status(401).body(response);
        }
    }
    
    /**
     * 用户登出接口
     */
    @PostMapping("/logout")
    public ResponseEntity<Map<String, Object>> logout(@RequestHeader("Authorization") String authHeader) {
        logger.info("收到用户登出请求");
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                logger.warn("登出失败：Token格式不正确，authHeader: {}", authHeader);
                response.put("success", false);
                response.put("message", "Token格式不正确");
                return ResponseEntity.status(400).body(response);
            }
            
            String token = authHeader.substring(7);
            logger.debug("开始删除Token: {}...", token.length() > 20 ? token.substring(0, 20) + "..." : token);
            
            // 获取用户信息用于日志记录
            UserInfoDto userInfo = tokenService.getUserByToken(token);
            String username = userInfo != null ? userInfo.getUsername() : "unknown";
            
            // 从 Redis 中删除 Token
            tokenService.removeToken(token);
            
            logger.info("用户登出成功，用户名: {}, Token已从Redis删除", username);
            
            response.put("success", true);
            response.put("message", "登出成功");
            response.put("serverPort", serverPort);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("用户登出过程中发生异常: {}", e.getMessage(), e);
            response.put("success", false);
            response.put("message", "登出失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }
    
    /**
     * 强制用户下线接口（删除用户所有Token）
     */
    @PostMapping("/force-logout/{userId}")
    public ResponseEntity<Map<String, Object>> forceLogout(@PathVariable Long userId) {
        logger.info("收到强制下线请求，用户ID: {}", userId);
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            logger.debug("开始删除用户所有Token，用户ID: {}", userId);
            
            // 删除用户所有Token
            tokenService.removeUserAllTokens(userId);
            
            logger.info("用户强制下线成功，用户ID: {}, 所有Token已从Redis删除", userId);
            
            response.put("success", true);
            response.put("message", "用户已强制下线");
            response.put("userId", userId);
            response.put("serverPort", serverPort);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            logger.error("强制下线过程中发生异常，用户ID: {}, 异常: {}", userId, e.getMessage(), e);
            response.put("success", false);
            response.put("message", "强制下线失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }
}